home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 21 / Cream of the Crop 21 (Terry Blount) (October 1996).iso / os2 / e33el2.zip / emacs / 19.33 / lisp / lisp-mnt.el < prev    next >
Text File  |  1996-02-17  |  18KB  |  555 lines

  1. ;;; lisp-mnt.el --- minor mode for Emacs Lisp maintainers
  2.  
  3. ;; Copyright (C) 1992, 1994 Free Software Foundation, Inc.
  4.  
  5. ;; Author: Eric S. Raymond <esr@snark.thyrsus.com>
  6. ;; Maintainer: Eric S. Raymond <esr@snark.thyrsus.com>
  7. ;; Created: 14 Jul 1992
  8. ;; Version: $Id: lisp-mnt.el,v 1.17 1996/02/08 04:13:11 rms Exp $
  9. ;; Keywords: docs
  10. ;; X-Bogus-Bureaucratic-Cruft: Gruad will get you if you don't watch out!
  11.  
  12. ;; This file is part of GNU Emacs.
  13.  
  14. ;; GNU Emacs is free software; you can redistribute it and/or modify
  15. ;; it under the terms of the GNU General Public License as published by
  16. ;; the Free Software Foundation; either version 2, or (at your option)
  17. ;; any later version.
  18.  
  19. ;; GNU Emacs is distributed in the hope that it will be useful,
  20. ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  21. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  22. ;; GNU General Public License for more details.
  23.  
  24. ;; You should have received a copy of the GNU General Public License
  25. ;; along with GNU Emacs; see the file COPYING.  If not, write to
  26. ;; the Free Software Foundation,  Inc., 59 Temple Place - Suite 330,
  27. ;; Boston, MA 02111-1307, USA.
  28.  
  29. ;;; Commentary:
  30.  
  31. ;; This minor mode adds some services to Emacs-Lisp editing mode.
  32. ;;
  33. ;; First, it knows about the header conventions for library packages.
  34. ;; One entry point supports generating synopses from a library directory.
  35. ;; Another can be used to check for missing headers in library files.
  36. ;; 
  37. ;; Another entry point automatically addresses bug mail to a package's
  38. ;; maintainer or author.
  39.  
  40. ;; This file can be loaded by your lisp-mode-hook.  Have it (require 'lisp-mnt)
  41.  
  42. ;; This file is an example of the header conventions.  Note the following
  43. ;; features:
  44. ;; 
  45. ;;    * Header line --- makes it possible to extract a one-line summary of
  46. ;; the package's uses automatically for use in library synopses, KWIC
  47. ;; indexes and the like.
  48. ;; 
  49. ;;    Format is three semicolons, followed by the filename, followed by
  50. ;; three dashes, followed by the summary.  All fields space-separated.
  51. ;; 
  52. ;;    * Author line --- contains the name and net address of at least
  53. ;; the principal author.
  54. ;; 
  55. ;;    If there are multiple authors, they should be listed on continuation
  56. ;; lines led by ;;<TAB>, like this:
  57. ;; 
  58. ;; ;; Author: Ashwin Ram <Ram-Ashwin@cs.yale.edu>
  59. ;; ;;    Dave Sill <de5@ornl.gov>
  60. ;; ;;    David Lawrence <tale@pawl.rpi.edu>
  61. ;; ;;    Noah Friedman <friedman@ai.mit.edu>
  62. ;; ;;    Joe Wells <jbw@maverick.uswest.com>
  63. ;; ;;    Dave Brennan <brennan@hal.com>
  64. ;; ;;    Eric Raymond <esr@snark.thyrsus.com>
  65. ;; 
  66. ;; This field may have some special values; notably "FSF", meaning
  67. ;; "Free Software Foundation".
  68. ;; 
  69. ;;    * Maintainer line --- should be a single name/address as in the Author
  70. ;; line, or an address only, or the string "FSF".  If there is no maintainer
  71. ;; line, the person(s) in the Author field are presumed to be it.  The example
  72. ;; in this file is mildly bogus because the maintainer line is redundant.
  73. ;;    The idea behind these two fields is to be able to write a Lisp function
  74. ;; that does "send mail to the author" without having to mine the name out by
  75. ;; hand. Please be careful about surrounding the network address with <> if
  76. ;; there's also a name in the field.
  77. ;; 
  78. ;;    * Created line --- optional, gives the original creation date of the
  79. ;; file.  For historical interest, basically.
  80. ;; 
  81. ;;    * Version line --- intended to give the reader a clue if they're looking
  82. ;; at a different version of the file than the one they're accustomed to.  This
  83. ;; may be an RCS or SCCS header.
  84. ;; 
  85. ;;    * Adapted-By line --- this is for FSF's internal use.  The person named
  86. ;; in this field was the one responsible for installing and adapting the
  87. ;; package for the distribution.  (This file doesn't have one because the
  88. ;; author *is* one of the maintainers.)
  89. ;; 
  90. ;;    * Keywords line --- used by the finder code (now under construction)
  91. ;; for finding Emacs Lisp code related to a topic.
  92. ;;
  93. ;;    * X-Bogus-Bureaucratic-Cruft line --- this is a joke and an example
  94. ;; of a comment header.  Headers starting with `X-' should never be used
  95. ;; for any real purpose; this is the way to safely add random headers
  96. ;; without invoking the wrath of any program.
  97. ;;
  98. ;;    * Commentary line --- enables Lisp code to find the developer's and
  99. ;; maintainers' explanations of the package internals.
  100. ;; 
  101. ;;    * Change log line --- optional, exists to terminate the commentary
  102. ;; section and start a change-log part, if one exists.
  103. ;; 
  104. ;;    * Code line --- exists so Lisp can know where commentary and/or
  105. ;; change-log sections end.
  106. ;; 
  107. ;;    * Footer line --- marks end-of-file so it can be distinguished from
  108. ;; an expanded formfeed or the results of truncation.
  109.  
  110. ;;; Change Log:
  111.  
  112. ;; Tue Jul 14 23:44:17 1992    ESR
  113. ;;    * Created.
  114.  
  115. ;;; Code:
  116.  
  117. (require 'picture)        ; provides move-to-column-force
  118. (require 'emacsbug)
  119.  
  120. ;;; Variables:
  121.  
  122. (defvar lm-header-prefix "^;;*[ \t]+\\(@\(#\)\\)?[ \t]*\\([\$]\\)?"
  123.   "Prefix that is ignored before the tag.
  124. For example, you can write the 1st line synopsis string and headers like this
  125. in your Lisp package:
  126.  
  127.    ;; @(#) package.el -- pacakge description
  128.    ;;
  129.    ;; @(#) $Maintainer:   Person Foo Bar $
  130.  
  131. The @(#) construct is used by unix what(1) and
  132. then $identifier: doc string $ is used by GNU ident(1)")
  133.  
  134. (defvar lm-comment-column 16
  135.   "Column used for placing formatted output.")
  136.  
  137. (defvar lm-commentary-header "Commentary\\|Documentation"
  138.   "Regexp which matches start of documentation section.")
  139.  
  140. (defvar lm-history-header "Change Log\\|History"
  141.   "Regexp which matches the start of code log section.")
  142.  
  143. ;;; Functions:
  144.  
  145. ;; These functions all parse the headers of the current buffer
  146.  
  147. (defsubst lm-get-header-re (header &optional mode)
  148.   "Returns regexp for matching HEADER.
  149. If called with optional MODE and with value `section',
  150. return section regexp instead."
  151.   (cond ((eq mode 'section)
  152.      (concat "^;;;;* " header ":[ \t]*$"))
  153.     (t
  154.      (concat lm-header-prefix header ":[ \t]*"))))
  155.  
  156. (defsubst lm-get-package-name ()
  157.   "Returns package name by looking at the first line."
  158.   (save-excursion
  159.     (goto-char (point-min))
  160.     (if (and (looking-at (concat lm-header-prefix))
  161.          (progn (goto-char (match-end 0))
  162.             (looking-at "\\([^\t ]+\\)")
  163.             (match-end 1)))
  164.     (buffer-substring (match-beginning 1) (match-end 1))
  165.       )))
  166.  
  167. (defun lm-section-mark (header &optional after)
  168.   "Return the buffer location of a given section start marker.
  169. The HEADER is the section mark string to search for.
  170. If AFTER is non-nil, return the location of the next line."
  171.   (save-excursion
  172.     (let ((case-fold-search t))
  173.       (goto-char (point-min))
  174.       (if (re-search-forward (lm-get-header-re header 'section) nil t)
  175.       (progn
  176.         (beginning-of-line)
  177.         (if after (forward-line 1))
  178.         (point))
  179.     nil))))
  180.  
  181. (defsubst lm-code-mark ()
  182.   "Return the buffer location of the `Code' start marker."
  183.   (lm-section-mark "Code"))
  184.  
  185. (defsubst lm-commentary-mark ()
  186.   "Return the buffer location of the `Commentary' start marker."
  187.   (lm-section-mark lm-commentary-header))
  188.  
  189. (defsubst lm-history-mark ()
  190.   "Return the buffer location of the `History' start marker."
  191.   (lm-section-mark lm-history-header))
  192.  
  193. (defun lm-header (header)
  194.   "Return the contents of the header named HEADER."
  195.   (goto-char (point-min))
  196.   (let ((case-fold-search t))
  197.     (if (and (re-search-forward (lm-get-header-re header) (lm-code-mark) t)
  198.          ;;   RCS ident likes format "$identifier: data$"
  199.          (looking-at "\\([^$\n]+\\)")
  200.          (match-end 1))
  201.     (buffer-substring (match-beginning 1) (match-end 1))
  202.       nil)))
  203.  
  204. (defun lm-header-multiline (header)
  205.   "Return the contents of the header named HEADER, with continuation lines.
  206. The returned value is a list of strings, one per line."
  207.   (save-excursion
  208.     (goto-char (point-min))
  209.     (let ((res (lm-header header)))
  210.       (cond
  211.        (res
  212.     (setq res (list res))
  213.     (forward-line 1)
  214.  
  215.     (while (and (looking-at (concat lm-header-prefix "[\t ]+"))
  216.             (progn
  217.               (goto-char (match